package com.ckjava.test.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 配置数据源和 Mybatis
 * @author chen_k
 *
 * 2017年8月22日-下午2:48:48
 */

@Configuration
//扫描 Mapper 接口并容器管理
@MapperScan(basePackages = DataSourceConfig.PACKAGE, sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {
	
	// 精确到 master 目录，以便跟其他数据源隔离
    public static final String PACKAGE = "com.ckjava.test.dao";
    public static final String MAPPER_LOCATION = "classpath:mapper/data/*Mapper.xml";
    public static final String CONFIG_LOCATION = "classpath:mapper/data/config.xml";

    /*
     *
     * 将 application.yml 的配置填充到 SpringBoot 中的 DataSourceProperties 对象里面
     */
    @Bean("druidConfig")
    @Primary
    @ConfigurationProperties(prefix = "datasource.druid")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean("druidDataSource")
    @Primary
    public DataSource dataSource(@Qualifier("druidConfig") DataSourceProperties dataSourceProperties) throws SQLException {
       // DataSourceProperties dataSourceProperties = dataSourceProperties();

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        dataSource.setUrl(dataSourceProperties.getUrl());
        dataSource.setUsername(dataSourceProperties.getUsername());
        dataSource.setPassword(dataSourceProperties.getPassword());

        // 配置初始化大小、最小、最大 
        dataSource.setInitialSize(1);
        dataSource.setMinIdle(3);
        dataSource.setMaxActive(20);
        
        // 配置获取连接等待超时的时间
        dataSource.setMaxWait(60000);
        // 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        
        // 配置一个连接在池中最小生存的时间，单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(300000);
        
        dataSource.setValidationQuery("SELECT 'x' FROM DUAL");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        
        // 配置监控统计拦截的filters
        dataSource.setFilters("stat");
        
        return dataSource;
    }

    @Bean(name = "transactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("druidDataSource") DataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("druidDataSource") DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(DataSourceConfig.MAPPER_LOCATION));
        sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(DataSourceConfig.CONFIG_LOCATION));
        return sessionFactory.getObject();
    }

}
